package yxy.cherry.future.message;

import com.google.protobuf.MessageLite;

import yxy.apple.logger.Logger;
import yxy.apple.util.IDGenerator;
import yxy.apple.util.redisson.RedisConnection;
import yxy.banana.socket.NetworkElement;
import yxy.cherry.future.Reactor;
import yxy.cherry.game.base.bean.GatewayBean;
import yxy.cherry.game.base.message.IMessageEmitter;
import yxy.cherry.game.base.message.annotation.MessageSource;
import yxy.cherry.game.base.redis.RedisManager;
import yxy.cherry.game.base.redis.RedisType;
import yxy.game.pm2.bean.PlayerBean;

public class MessageEmitter implements IMessageEmitter {
	protected static Logger logger = Logger.create(MessageEmitter.class);

	static private MessageEmitter instance;

	static public MessageEmitter getInstance() {
		if (instance == null) {
			instance = new MessageEmitter();
		}
		return instance;
	}

	private MessageEmitter() {
	}

	@Override
	public boolean send(int uid, MessageLite message) {
		int proto = 0;
		try {
			proto = (int) message.getClass().getDeclaredMethod("getProto").invoke(message);
		} catch (Exception e) {
			logger.warn("发送消息时 proto 属性不存在");
		}
		try {
			RedisConnection redis = RedisManager.getInstance().getConnection(RedisType.REDIS_USER);
			GatewayBean gateway = GatewayBean.find(redis, uid);
			String tag = IDGenerator.nextUUID();
			long s = 0;
			long d = NetworkElement.value(gateway.getSystem(), gateway.getCluster(), gateway.getChannel());
			Reactor.instance.bundler().balance().send(tag, s, d, proto, message);
//			logger.info("message send::::<<<<<<::[0x%08x] %s", proto, message.getClass().getName());//XXX 指令输出
			return true;
		} catch (Exception e) {
			logger.error("发送消息时出现错误 - %s", e.getCause());
		}
		return false;
	}

	@Override
	public boolean send(String pcode, MessageLite message) {
		try {
			PlayerBean playerBean = PlayerBean.get(pcode);
			return send(playerBean.getUid(), message);
		} catch (Exception e) {
			logger.error("发送消息时出现错误 - %s", e.getCause());
		}
		return false;
	}

	@Override
	public boolean send(MessageSource source, MessageLite message) {
		int proto = 0;
		try {
			proto = (int) message.getClass().getDeclaredMethod("getProto").invoke(message);
		} catch (Exception e) {
			logger.warn("发送消息时 proto 属性不存在");
		}
		try {
			Reactor.instance.bundler().balance().send(source.getTag(), source.getDestination(), source.getSource(), proto, message);
//			logger.info("message send::<<<<<<::::[0x%08x] %s", proto, message.getClass().getName());//XXX 指令输出
			return true;
		} catch (Exception e) {
			logger.error("发送消息时出现错误 - %s", e.getCause());
		}
		return false;
	}

	@Override
	public boolean control(String tag, long source, long destination, int proto, MessageLite message) {
		return false;
	}
}
